{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3723, 92)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>id</th>\n",
       "      <th>listing_url</th>\n",
       "      <th>scrape_id</th>\n",
       "      <th>last_scraped</th>\n",
       "      <th>name</th>\n",
       "      <th>summary</th>\n",
       "      <th>space</th>\n",
       "      <th>description</th>\n",
       "      <th>experiences_offered</th>\n",
       "      <th>neighborhood_overview</th>\n",
       "      <th>...</th>\n",
       "      <th>review_scores_value</th>\n",
       "      <th>requires_license</th>\n",
       "      <th>license</th>\n",
       "      <th>jurisdiction_names</th>\n",
       "      <th>instant_bookable</th>\n",
       "      <th>cancellation_policy</th>\n",
       "      <th>require_guest_profile_picture</th>\n",
       "      <th>require_guest_phone_verification</th>\n",
       "      <th>calculated_host_listings_count</th>\n",
       "      <th>reviews_per_month</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>7087327</td>\n",
       "      <td>https://www.airbnb.com/rooms/7087327</td>\n",
       "      <td>20151002231825</td>\n",
       "      <td>2015-10-03</td>\n",
       "      <td>Historic DC Condo-Walk to Capitol!</td>\n",
       "      <td>Professional pictures coming soon! Welcome to ...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Professional pictures coming soon! Welcome to ...</td>\n",
       "      <td>none</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>f</td>\n",
       "      <td>NaN</td>\n",
       "      <td>DISTRICT OF COLUMBIA, WASHINGTON</td>\n",
       "      <td>f</td>\n",
       "      <td>flexible</td>\n",
       "      <td>f</td>\n",
       "      <td>f</td>\n",
       "      <td>18</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>975833</td>\n",
       "      <td>https://www.airbnb.com/rooms/975833</td>\n",
       "      <td>20151002231825</td>\n",
       "      <td>2015-10-03</td>\n",
       "      <td>Spacious Capitol Hill Townhouse</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Beautifully renovated Capitol Hill townhouse. ...</td>\n",
       "      <td>Beautifully renovated Capitol Hill townhouse. ...</td>\n",
       "      <td>none</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>9.0</td>\n",
       "      <td>f</td>\n",
       "      <td>NaN</td>\n",
       "      <td>DISTRICT OF COLUMBIA, WASHINGTON</td>\n",
       "      <td>f</td>\n",
       "      <td>strict</td>\n",
       "      <td>f</td>\n",
       "      <td>f</td>\n",
       "      <td>1</td>\n",
       "      <td>2.11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>8249488</td>\n",
       "      <td>https://www.airbnb.com/rooms/8249488</td>\n",
       "      <td>20151002231825</td>\n",
       "      <td>2015-10-03</td>\n",
       "      <td>Spacious/private room for single</td>\n",
       "      <td>This is an ideal room for a single traveler th...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>This is an ideal room for a single traveler th...</td>\n",
       "      <td>none</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>f</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>f</td>\n",
       "      <td>flexible</td>\n",
       "      <td>f</td>\n",
       "      <td>f</td>\n",
       "      <td>1</td>\n",
       "      <td>1.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>8409022</td>\n",
       "      <td>https://www.airbnb.com/rooms/8409022</td>\n",
       "      <td>20151002231825</td>\n",
       "      <td>2015-10-03</td>\n",
       "      <td>A wonderful bedroom with library</td>\n",
       "      <td>Prime location right on the Potomac River in W...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Prime location right on the Potomac River in W...</td>\n",
       "      <td>none</td>\n",
       "      <td>NaN</td>\n",
       "      <td>...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>f</td>\n",
       "      <td>NaN</td>\n",
       "      <td>DISTRICT OF COLUMBIA, WASHINGTON</td>\n",
       "      <td>f</td>\n",
       "      <td>flexible</td>\n",
       "      <td>f</td>\n",
       "      <td>f</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>8411173</td>\n",
       "      <td>https://www.airbnb.com/rooms/8411173</td>\n",
       "      <td>20151002231825</td>\n",
       "      <td>2015-10-03</td>\n",
       "      <td>Downtown Silver Spring</td>\n",
       "      <td>Hi travellers! I live in this peaceful spot, b...</td>\n",
       "      <td>This is a 750 sq ft 1 bedroom 1 bathroom.  Whi...</td>\n",
       "      <td>Hi travellers! I live in this peaceful spot, b...</td>\n",
       "      <td>none</td>\n",
       "      <td>Silver Spring is booming.  You can walk to a n...</td>\n",
       "      <td>...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>f</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>f</td>\n",
       "      <td>flexible</td>\n",
       "      <td>f</td>\n",
       "      <td>f</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 92 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "        id                           listing_url       scrape_id last_scraped  \\\n",
       "0  7087327  https://www.airbnb.com/rooms/7087327  20151002231825   2015-10-03   \n",
       "1   975833   https://www.airbnb.com/rooms/975833  20151002231825   2015-10-03   \n",
       "2  8249488  https://www.airbnb.com/rooms/8249488  20151002231825   2015-10-03   \n",
       "3  8409022  https://www.airbnb.com/rooms/8409022  20151002231825   2015-10-03   \n",
       "4  8411173  https://www.airbnb.com/rooms/8411173  20151002231825   2015-10-03   \n",
       "\n",
       "                                 name  \\\n",
       "0  Historic DC Condo-Walk to Capitol!   \n",
       "1     Spacious Capitol Hill Townhouse   \n",
       "2    Spacious/private room for single   \n",
       "3    A wonderful bedroom with library   \n",
       "4              Downtown Silver Spring   \n",
       "\n",
       "                                             summary  \\\n",
       "0  Professional pictures coming soon! Welcome to ...   \n",
       "1                                                NaN   \n",
       "2  This is an ideal room for a single traveler th...   \n",
       "3  Prime location right on the Potomac River in W...   \n",
       "4  Hi travellers! I live in this peaceful spot, b...   \n",
       "\n",
       "                                               space  \\\n",
       "0                                                NaN   \n",
       "1  Beautifully renovated Capitol Hill townhouse. ...   \n",
       "2                                                NaN   \n",
       "3                                                NaN   \n",
       "4  This is a 750 sq ft 1 bedroom 1 bathroom.  Whi...   \n",
       "\n",
       "                                         description experiences_offered  \\\n",
       "0  Professional pictures coming soon! Welcome to ...                none   \n",
       "1  Beautifully renovated Capitol Hill townhouse. ...                none   \n",
       "2  This is an ideal room for a single traveler th...                none   \n",
       "3  Prime location right on the Potomac River in W...                none   \n",
       "4  Hi travellers! I live in this peaceful spot, b...                none   \n",
       "\n",
       "                               neighborhood_overview        ...         \\\n",
       "0                                                NaN        ...          \n",
       "1                                                NaN        ...          \n",
       "2                                                NaN        ...          \n",
       "3                                                NaN        ...          \n",
       "4  Silver Spring is booming.  You can walk to a n...        ...          \n",
       "\n",
       "  review_scores_value requires_license license  \\\n",
       "0                 NaN                f     NaN   \n",
       "1                 9.0                f     NaN   \n",
       "2                 NaN                f     NaN   \n",
       "3                 NaN                f     NaN   \n",
       "4                 NaN                f     NaN   \n",
       "\n",
       "                 jurisdiction_names instant_bookable cancellation_policy  \\\n",
       "0  DISTRICT OF COLUMBIA, WASHINGTON                f            flexible   \n",
       "1  DISTRICT OF COLUMBIA, WASHINGTON                f              strict   \n",
       "2                               NaN                f            flexible   \n",
       "3  DISTRICT OF COLUMBIA, WASHINGTON                f            flexible   \n",
       "4                               NaN                f            flexible   \n",
       "\n",
       "   require_guest_profile_picture require_guest_phone_verification  \\\n",
       "0                              f                                f   \n",
       "1                              f                                f   \n",
       "2                              f                                f   \n",
       "3                              f                                f   \n",
       "4                              f                                f   \n",
       "\n",
       "  calculated_host_listings_count reviews_per_month  \n",
       "0                             18               NaN  \n",
       "1                              1              2.11  \n",
       "2                              1              1.00  \n",
       "3                              1               NaN  \n",
       "4                              1               NaN  \n",
       "\n",
       "[5 rows x 92 columns]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "features = ['accommodates', 'bedrooms', 'bathrooms', 'beds', 'price', 'minimum_nights', 'maximum_nights', 'number_of_reviews']\n",
    "dc_listings = pd.read_csv('listings.csv')\n",
    "print(dc_listings.shape)\n",
    "dc_listings.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0      461\n",
       "1     2294\n",
       "2      503\n",
       "3      279\n",
       "4       35\n",
       "5       73\n",
       "6       17\n",
       "7       22\n",
       "8        7\n",
       "9       12\n",
       "10       2\n",
       "11       4\n",
       "12       6\n",
       "13       8\n",
       "Name: distance, dtype: int64"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "our_acc_value = 3# 有三个房间\n",
    "dc_listings['distance'] = np.abs(dc_listings['accommodates']-our_acc_value)# 房间数与3的差值\n",
    "dc_listings['distance'].value_counts().sort_index()# 统计各差值数量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>distance</th>\n",
       "      <th>price</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2645</th>\n",
       "      <td>0</td>\n",
       "      <td>$75.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2825</th>\n",
       "      <td>0</td>\n",
       "      <td>$120.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2145</th>\n",
       "      <td>0</td>\n",
       "      <td>$90.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2541</th>\n",
       "      <td>0</td>\n",
       "      <td>$50.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3349</th>\n",
       "      <td>0</td>\n",
       "      <td>$105.00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      distance    price\n",
       "2645         0   $75.00\n",
       "2825         0  $120.00\n",
       "2145         0   $90.00\n",
       "2541         0   $50.00\n",
       "3349         0  $105.00"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dc_listings = dc_listings.sample(frac=1, random_state=0)# 将数据打乱顺序\n",
    "dc_listings = dc_listings.sort_values('distance')# 根据距离排序\n",
    "dc_listings[['distance', 'price']].head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "88.0"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dc_listings['price'] = dc_listings['price'].str.replace('\\$|,','').astype(float)# 将$符号替换掉\n",
    "mean_price = dc_listings['price'].iloc[:5].mean()# 计算价格平均值\n",
    "mean_price"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "dc_listings.drop('distance', axis=1, inplace=True)\n",
    "\n",
    "train_df = dc_listings.copy().iloc[:2792]# 训练集\n",
    "test_df = dc_listings.copy().iloc[2792:]# 测试集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# train_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 基于单变量预测价格\n",
    "def predict_price(new_listing_value, feature_column):\n",
    "    temp_df = train_df\n",
    "#     temp_df['distance'] = np.abs(dc_listings[feature_column]-new_listing_value)# 计算距离\n",
    "    temp_df['distance'] = np.abs(train_df[feature_column]-new_listing_value)# 计算距离\n",
    "    temp_df = temp_df.sort_values('distance')# 按距离排序\n",
    "    knn_5 = temp_df['price'].iloc[:5]# 取前5条数据，k=5\n",
    "    predict_price = knn_5.mean()#取平均值进行预测\n",
    "    return predict_price"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_df['predict_price'] = test_df['accommodates'].apply(predict_price, feature_column='accommodates')# apply，对每条样本执行同样的操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "212.98927967051529"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算均方根误差RMSE\n",
    "test_df['squared_error'] = (test_df['predict_price']-test_df['price'])**(2)\n",
    "mse = test_df['squared_error'].mean()\n",
    "rmse = mse ** (1/2)\n",
    "rmse# 对于一个变量的模型评估得分，误差过大"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RMSE for the accommodates coloumn: 212.9892796705153\n",
      "RMSE for the bedrooms coloumn: 199.80935328065047\n",
      "RMSE for the bathrooms coloumn: 230.2471670568422\n",
      "RMSE for the beds coloumn: 227.7858424753905\n",
      "RMSE for the number_of_reviews coloumn: 235.91327066995507\n"
     ]
    }
   ],
   "source": [
    "for feature in ['accommodates', 'bedrooms', 'bathrooms', 'beds', 'number_of_reviews']:\n",
    "    test_df['predicted_price'] = test_df[feature].apply(predict_price, feature_column=feature)\n",
    "    test_df['squared_error'] = (test_df['predicted_price']-test_df['price'])**(2)\n",
    "    mse = test_df['squared_error'].mean()\n",
    "    rmse = mse ** (1/2)\n",
    "    print('RMSE for the {} coloumn: {}'.format(feature, rmse))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\python\\lib\\site-packages\\sklearn\\preprocessing\\data.py:617: DataConversionWarning: Data with input dtype int64, float64 were all converted to float64 by StandardScaler.\n",
      "  return self.partial_fit(X, y)\n",
      "d:\\python\\lib\\site-packages\\sklearn\\base.py:462: DataConversionWarning: Data with input dtype int64, float64 were all converted to float64 by StandardScaler.\n",
      "  return self.fit(X, **fit_params).transform(X)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3671, 8)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>accommodates</th>\n",
       "      <th>bedrooms</th>\n",
       "      <th>bathrooms</th>\n",
       "      <th>beds</th>\n",
       "      <th>price</th>\n",
       "      <th>minimum_nights</th>\n",
       "      <th>maximum_nights</th>\n",
       "      <th>number_of_reviews</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.401420</td>\n",
       "      <td>-0.249501</td>\n",
       "      <td>-0.439211</td>\n",
       "      <td>0.297386</td>\n",
       "      <td>0.081119</td>\n",
       "      <td>-0.341421</td>\n",
       "      <td>-0.016575</td>\n",
       "      <td>-0.516779</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.399466</td>\n",
       "      <td>2.129508</td>\n",
       "      <td>2.969551</td>\n",
       "      <td>1.141704</td>\n",
       "      <td>1.462622</td>\n",
       "      <td>-0.065047</td>\n",
       "      <td>-0.016606</td>\n",
       "      <td>1.706767</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-1.095648</td>\n",
       "      <td>-0.249501</td>\n",
       "      <td>1.265170</td>\n",
       "      <td>-0.546933</td>\n",
       "      <td>-0.718699</td>\n",
       "      <td>-0.065047</td>\n",
       "      <td>-0.016575</td>\n",
       "      <td>-0.482571</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-0.596625</td>\n",
       "      <td>-0.249501</td>\n",
       "      <td>-0.439211</td>\n",
       "      <td>-0.546933</td>\n",
       "      <td>-0.391501</td>\n",
       "      <td>-0.341421</td>\n",
       "      <td>-0.016575</td>\n",
       "      <td>-0.516779</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.401420</td>\n",
       "      <td>-0.249501</td>\n",
       "      <td>-0.439211</td>\n",
       "      <td>-0.546933</td>\n",
       "      <td>-0.718699</td>\n",
       "      <td>1.316824</td>\n",
       "      <td>-0.016575</td>\n",
       "      <td>-0.516779</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   accommodates  bedrooms  bathrooms      beds     price  minimum_nights  \\\n",
       "0      0.401420 -0.249501  -0.439211  0.297386  0.081119       -0.341421   \n",
       "1      1.399466  2.129508   2.969551  1.141704  1.462622       -0.065047   \n",
       "2     -1.095648 -0.249501   1.265170 -0.546933 -0.718699       -0.065047   \n",
       "3     -0.596625 -0.249501  -0.439211 -0.546933 -0.391501       -0.341421   \n",
       "4      0.401420 -0.249501  -0.439211 -0.546933 -0.718699        1.316824   \n",
       "\n",
       "   maximum_nights  number_of_reviews  \n",
       "0       -0.016575          -0.516779  \n",
       "1       -0.016606           1.706767  \n",
       "2       -0.016575          -0.482571  \n",
       "3       -0.016575          -0.516779  \n",
       "4       -0.016575          -0.516779  "
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 利用sklearn库进行特征标准化进行数据预处理\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "features = ['accommodates', 'bedrooms', 'bathrooms', 'beds', 'price', 'minimum_nights', 'maximum_nights', 'number_of_reviews']\n",
    "dc_listings = pd.read_csv('listings.csv')\n",
    "dc_listings = dc_listings[features]\n",
    "dc_listings['price'] = dc_listings['price'].str.replace('\\$|,','').astype(float)# 处理$\n",
    "dc_listings = dc_listings.dropna()# 去掉缺失值\n",
    "dc_listings[features] = StandardScaler().fit_transform(dc_listings[features])# 特征标准化处理\n",
    "normalized_listings = dc_listings\n",
    "print(dc_listings.shape)\n",
    "normalized_listings.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "norm_train_df = normalized_listings.copy().iloc[:2792]\n",
    "norm_test_df = normalized_listings.copy().iloc[2792:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.723019604017032"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from scipy.spatial import distance# 使用scipy库计算欧式距离\n",
    "\n",
    "first_listings = normalized_listings.iloc[0][['accommodates', 'bathrooms']]\n",
    "fifth_listings = normalized_listings.iloc[20][['accommodates', 'bathrooms']]\n",
    "first_fifth_distance = distance.euclidean(first_listings, fifth_listings)\n",
    "first_fifth_distance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.789406392258\n"
     ]
    }
   ],
   "source": [
    "# 多变量KNN模型\n",
    "def predict_price_multivariate(new_listing_value, feature_columns):\n",
    "    temp_df = norm_train_df\n",
    "    temp_df['distance'] = distance.cdist(temp_df[feature_columns], [new_listing_value[feature_columns]])# 求欧式距离\n",
    "    temp_df = temp_df.sort_values('distance')# 根据距离排序\n",
    "    knn5 = temp_df['price'].iloc[:5]# 取前5个值\n",
    "    predicted_price = knn5.mean()# 求平均数\n",
    "    return predicted_price\n",
    "\n",
    "cols = ['accommodates', 'bathrooms']\n",
    "norm_test_df['predicted_price'] = norm_test_df[cols].apply(predict_price_multivariate, feature_columns=cols, axis=1)\n",
    "norm_test_df['squared_error'] = (norm_test_df['predicted_price'] - norm_test_df['price']) ** (2)\n",
    "mse = norm_test_df['squared_error'].mean()\n",
    "rmse = mse ** (1/2)\n",
    "print(rmse)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 使用Sklearn完成KNN\n",
    "from sklearn.neighbors import KNeighborsRegressor\n",
    "cols = ['accommodates', 'bathrooms']\n",
    "knn = KNeighborsRegressor(n_neighbors=10)# 设置knn，默认值为5\n",
    "knn.fit(norm_train_df[cols], norm_train_df['price'])# 进行模型训练\n",
    "two_features_predictions = knn.predict(norm_test_df[cols])# 预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.824222726134\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import mean_squared_error\n",
    "\n",
    "two_features_mse = mean_squared_error(norm_test_df['price'], two_features_predictions)\n",
    "two_features_rmse = two_features_mse ** (1/2)\n",
    "print(two_features_rmse)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.801731509444\n"
     ]
    }
   ],
   "source": [
    "# 加入更多的特征\n",
    "cols = ['accommodates', 'bedrooms', 'bathrooms', 'beds', 'minimum_nights', 'maximum_nights', 'number_of_reviews']\n",
    "knn.fit(norm_train_df[cols], norm_train_df['price'])\n",
    "four_features_predictions = knn.predict(norm_test_df[cols])\n",
    "four_features_mse = mean_squared_error(norm_test_df['price'], four_features_predictions)\n",
    "four_features_rmse = four_features_mse ** (1/2)\n",
    "print(four_features_rmse)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
